package com.slowfly.rule.engine.component;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 钉钉消息
 */
@Data
@Slf4j
@Component
@ConfigurationProperties(prefix = "dingtalk")
public class DingTalkComponent {

    private String serverUrl;
    private String accessToken;
    private String secret;

    private static DingTalkClient client;

    @PostConstruct
    public void init() {
        try {
            client = new DefaultDingTalkClient(serverUrl + params(accessToken, secret));
        } catch (Exception e) {
            log.error("init error", e);
        }
    }

    public void sendFuseMessage(Integer strategyId, String strategyName, long rejectCount, long totalCount) {
        String contentFormat = "策略%s (%s) 在 %s 发生熔断 (%s/%s)，请查看原因。";
        String content = String.format(contentFormat, strategyId, strategyName, DateUtil.now(), rejectCount, totalCount);
        log.info("sendFuseMessage {}", content);
        sendTextMessage(content);
    }

    /**
     * 发送普通文本消息
     */
    private void sendTextMessage(String content) {
        OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
        text.setContent(content);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("text");
        request.setText(text);
        try {
            OapiRobotSendResponse response = client.execute(request);
            log.info("sendTextMessage success {}", JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("sendTextMessage error {}", content, e);
        }
    }

    private String params(String accessToken, String secret) throws Exception {
        Long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        return "?access_token=" + accessToken + "&timestamp=" + timestamp + "&sign=" + sign;
    }
}
